#coding=utf-8
from bvuserapp.models import User
import pickle
from django.conf import settings
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseNotFound, \
    HttpResponseNotAllowed
from django.utils.translation import ugettext as _
from forms import BlogPostForm, CommentForm
from models import BlogPost, PostComment, Tag, PostTag
from ragendja.dbutils import get_object, get_object_or_404, get_object_list, prefetch_references, get_list_or_404
from ragendja.template import render_to_response
import logging
from google.appengine.ext.db import Key
from utils import captcha
from utils.flash import Flash
from django.core.cache import cache


cache_timeout = getattr(settings, 'CACHE_TIMEOUT', 2592000)


class Paginator():
    
    def __init__(self, query, page, user=None, on_page=None):

        self.page = page
        self.post_on_page = on_page or getattr(settings, 'BLOG_POSTS_ON_PAGE', 10)
        
        pages_count_float = query.count() / float(self.post_on_page)  
        self.pages_count = (pages_count_float) if (pages_count_float)==int(pages_count_float) else int(pages_count_float)+1 
        self.page_range = range(1, int(self.pages_count)+1) 
        self.object_list = query.fetch(self.post_on_page, (self.page-1)*self.post_on_page)
        self.has_next_page = True if self.page < self.pages_count else False 
        self.next_page = self.page+1
        self.has_prev_page = True if self.page>1 else False
        self.prev_page = self.page-1    



def index(request, username):
    flash = Flash()
    user = get_object_or_404(User, 'username = ', username)
    query = None
    if request.user == user:
        query = get_object_list(BlogPost, "author = ", user)
        if query.count()==0:
            return HttpResponseRedirect(reverse('blog_create', args=[username]))
    else:
        query = get_object_list(BlogPost, "author = ", user, 'is_private = ', False)
    paginator = Paginator(query.order("-created_at"), request.page)
    tags = get_object_list(Tag, "namespace = ", user.username, "count > ", 0).order('-count').fetch(25)
    data = {'paginator': paginator, 'username': username, 'tags': tags, 'flash': flash}
    return render_to_response(request, 'bvblogapp/index.html', data)
        

def search_by_tag(request, username, tagname):
    logging.info('search_by_tag')
    flash = Flash()
    user = get_object_or_404(User, 'username = ', username)
    tag = get_object_or_404(Tag, 'tag = ', tagname, 'namespace = ', user.username)
    logging.debug(tag) 
    post_tags = get_object_list(PostTag, 'tag = ', tag).order('-created_at')
    prefetch_references(post_tags, 'post')
    paginator = Paginator(post_tags, request.page)
    paginator.object_list = map(lambda x: x.post, paginator.object_list)    
    if request.user != user:
        paginator.object_list = filter(lambda x: x.is_private == False, paginator.object_list)
    tags = get_object_list(Tag, "namespace = ", user.username, "count > ", 0).order('-count').fetch(25)
    data = {'paginator': paginator, 'username': username, 'tags': tags, 'tag': tag, 'flash': flash} 
    return render_to_response(request, 'bvblogapp/search_by_tag.html', data)
    
    
    
def search_by_public_tag(request, tagname):
    logging.info('search_by_public_tag')
    flash = Flash()        
    logging.debug('tagname: %s' % tagname)
    tag = get_list_or_404(Tag, 'tag = ', tagname).fetch(30) 
    logging.debug(tag) 
    post_tags = get_object_list(PostTag, 'tag IN ', tag).order('-created_at')
    prefetch_references(post_tags, 'post')
    paginator = Paginator(post_tags, request.page)
    paginator.object_list = map(lambda x: x.post, paginator.object_list)    
    paginator.object_list = filter(lambda x: x.is_private == False, paginator.object_list)    
    tags = get_object_list(Tag, "count > ", 0).order('-count').fetch(25)
    data = {'paginator': paginator, 'tags': tags, 'tag': tag, 'flash': flash} 
    return render_to_response(request, 'bvblogapp/search_by_public_tag.html', data)

@login_required    
def update(request, username, post_key=''):
    flash = Flash()
    post_id = None
    old_tags = ''
    if post_key != '':
        logging.debug('update: post_key=%s' % post_key)
        post = get_object_or_404(BlogPost, id=long(post_key))

        if request.user != post.author:
            return HttpResponseNotAllowed('You can\'t view this analysis.')        
        
        old_tags = post.tags or ''
        logging.debug('update: old_tags=%s' % old_tags)
        if not post.can_edit_by(request.user):
            return HttpResponseNotAllowed(_('You are not allowed to edit this post'))
            
        post_id = post.key().id()
         
    if request.method == 'POST':
        if post_id: post.update_old_tags(old_tags)
        form = BlogPostForm(request.POST, instance=post) if post_key != '' else BlogPostForm(request.POST)
        
        if request.POST.has_key('external_data')==False and form.is_valid():
            post = form.save(commit=False)
            post.author = request.user            
            post.author_username = request.user.username

            post.save()                        
            form.save_m2m()
            post.save_tags()
            
            flash.msg = _('Blog was updated.')
            
            return HttpResponseRedirect(reverse('blog_post_read', kwargs={'username': request.user.username, 'post_key': post.key().id()}))
    else:
        form = BlogPostForm(instance=post) if post_key != '' else BlogPostForm()

    return render_to_response(request, 'bvblogapp/create.html', {'form': form, 'post_id': post_id, 'flash': flash})



def read(request, username, post_key):
    flash = Flash()
    post = get_object_or_404(BlogPost, id=int(post_key))
    query = None
    if request.user != post.author and post.is_private == True:
        return HttpResponseNotAllowed('You can\'t view this analysis.')
    comments = get_object_list(PostComment, 'post = ', post).order('created_at').fetch(1000)    
    data = {'post': post, 'comments': comments, 'post_id': int(post_key), 'username': username, 'comment_form': CommentForm(), 'flash': flash} 
    return render_to_response(request, 'bvblogapp/read.html', data)


@login_required
def delete(request, username, post_key):
    flash = Flash()
    post = get_object_or_404(BlogPost, id=int(post_key))
    if not post.can_edit_by(request.user):
        return HttpResponseNotAllowed(_('You are not allowed to delete this post'))
       
    if request.method == 'POST':
        old_tags = post.tags or ''
        post.update_old_tags(old_tags)
        post.delete()

        flash.msg = _('Post was deleted.')
        
        return HttpResponseRedirect(reverse('blog_index', args=(username,)))
    
    logging.debug('post_id %s' % post.key().id())
    return render_to_response(request, 'bvblogapp/delete.html', {'post_id': post.key().id(), 'flash': flash})
    


def add_comment(request, username, post_key):
    flash = Flash()    
    if request.method == 'POST':
        
        post = get_object_or_404(BlogPost, id=int(post_key))
        
        form = CommentForm(request.POST, initial={'captcha': request.META['REMOTE_ADDR']})
        
        if form.is_valid():
            comment = form.save(commit=False)
            comment.author = request.user
            comment.post = post
            comment.save()
            form.save_m2m()
            

            flash.msg = _('Comment was added.')
        else:
            flash.msg = ' '.join(map(lambda x: ' '.join(x), [item for item in form.errors.itervalues()]))


    return HttpResponseRedirect(reverse('blog_post_read', args=(username, post_key)))

        
        
def delete_comment(request, username, post_key, comment_id):
    comment = get_object_or_404(PostComment, id=int(comment_id))
    if not comment.can_deleted_by(request.user):
        return HttpResponseNotAllowed(_('You are not allowed to delete this comment'))
    comment.delete()
    flash = Flash()
    flash.msg = _('Comment was deleted.')
    return HttpResponseRedirect(reverse('blog_post_read', args=(username, post_key)))


        
def latests_posts(request):
    flash = Flash()
    paginator = Paginator(get_object_list(BlogPost, 'is_private = ', False).order("-created_at"), request.page)    
    tags = get_object_list(Tag, "count > ", 0).order('-count').fetch(25)
    data = {'paginator': paginator, 'flash': flash, 'tags': tags}
    return render_to_response(request, 'bvblogapp/latests.html', data)


def users(request):
    flash = Flash()
    users = get_list_or_404(User).order('username')
    paginator = Paginator(users, request.page, on_page=24)
    return render_to_response(request, 'bvblogapp/users.html', {'paginator' : paginator})
